package classconverstation.cscl.ist.psu.edu.client.classcommons;

import java.util.ArrayList;
import java.util.Date;


import classconverstation.cscl.ist.psu.edu.client.CommonObject;
import classconverstation.cscl.ist.psu.edu.client.messengers.ClassCommonsMessage;
import classconverstation.cscl.ist.psu.edu.client.messengers.User;
import classconverstation.cscl.ist.psu.edu.client.services.ClassCommonsService;
import classconverstation.cscl.ist.psu.edu.client.services.ClassCommonsServiceAsync;
import classconverstation.cscl.ist.psu.edu.client.services.LoginService;
import classconverstation.cscl.ist.psu.edu.client.services.LoginServiceAsync;
import classconverstation.cscl.ist.psu.edu.client.util.ClassConversationUtil;

import com.allen_sauer.gwt.log.client.Log;
import com.google.code.p.gwtchismes.client.GWTCPopupBox;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.JsArray;
import com.google.gwt.event.dom.client.BlurEvent;
import com.google.gwt.event.dom.client.BlurHandler;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.FocusEvent;
import com.google.gwt.event.dom.client.FocusHandler;
import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.RequestBuilder;
import com.google.gwt.http.client.RequestCallback;
import com.google.gwt.http.client.RequestException;
import com.google.gwt.http.client.Response;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CaptionPanel;
import com.google.gwt.user.client.ui.FileUpload;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.FormPanel;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.Hidden;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.FormPanel.SubmitCompleteEvent;
import com.google.gwt.user.client.ui.FormPanel.SubmitEvent;

public class ClassCommons implements EntryPoint {
	FlowPanel headerPanel;
	FlowPanel postingPanel;
	FlowPanel messagePanel;
	FlowPanel messageListPanel;
	private LoginServiceAsync loginServiceSvc = GWT.create(LoginService.class);
	private ClassCommonsServiceAsync classCommonsServiceSvc = GWT.create(ClassCommonsService.class);
	User user;
	TextArea postArea;
	TextBox vBox;
	TextBox iBox;
	String cname;

	Label forumHeader;
	int cid; 
	ArrayList<ClassCommonsMessage> cm_msgs = new ArrayList<ClassCommonsMessage>();
	// Real time ClassCommons Messages
	ArrayList<ClassCommonsMessage> stack_msgs = new ArrayList<ClassCommonsMessage>();
	// Pin messages
	ArrayList<ClassCommonsMessage> pin_msgs = new ArrayList<ClassCommonsMessage>();
	String[] imageFormats = {"jpg", "gif", "tiff", "png"};


	public void onModuleLoad() {
		cname = Window.Location.getParameter("cname");
		headerPanel = new FlowPanel();

		Label classHeader = new Label("ClassConversation - "+cname);
		forumHeader = new Label("Go to the Forum");
		forumHeader.addStyleDependentName("forumLink");

		headerPanel.add(classHeader);
		headerPanel.add(forumHeader);
		//RootPanel.get("header").add(classHeader);
		RootPanel.get("header").add(headerPanel);
		FlowPanel container = new FlowPanel();
		postingPanel = getPostingPanel();
		messagePanel = getMessagePanel();

		int width = (int) (0.6*Window.getClientWidth());
		container.setWidth(width+"px");
		RootPanel.get("center").add(container);
		container.add(postingPanel);
		container.add(messagePanel);

		FlowPanel footer = new FlowPanel();
		String html = "<div id = 'copyright' style = 'margin-top: 10px;'> Copyright @ CSCL Lab, Penn State University </div>";
		HTMLPanel hPanel = new HTMLPanel(html);
		footer.add(hPanel);
		RootPanel.get("footer").add(footer);
		loginFromSession();
	}


	public FlowPanel getPostingPanel(){
		FlowPanel fPanel = new FlowPanel();
		fPanel.addStyleName("marginBottom20");

		Label tip = new Label("Post what you want to say here ...");
		tip.addStyleDependentName("tip");

		postArea = new TextArea();
		postArea.setVisibleLines(5);
		int width = (int) (0.6*Window.getClientWidth());
		postArea.setWidth(width+"px");


		FlowPanel postOptionsPanel = new FlowPanel();
		postOptionsPanel.addStyleName("floatRight");

		Label image = new Label("Image");
		Label video = new Label("Video");
		Label bar = new Label("|");

		image.addStyleDependentName("linkleft");
		video.addStyleDependentName("linkleft");
		bar.addStyleDependentName("bar");
		postOptionsPanel.add(image);
		postOptionsPanel.add(bar);
		postOptionsPanel.add(video);

		final FlowPanel vPanel = this.getVideoURLPanel();
		vPanel.setVisible(false);
		vPanel.addStyleName("margintop");

		final FlowPanel iPanel = this.getImageURLPanel();
		iPanel.setVisible(false);		
		iPanel.addStyleName("margintop");
		image.addClickHandler(new ClickHandler(){


			public void onClick(ClickEvent event) {
				if (!iPanel.isVisible()){
					iPanel.setVisible(true);
					vPanel.setVisible(false);
				}
			}
		});
		video.addClickHandler(new ClickHandler(){


			public void onClick(ClickEvent event) {
				if (!vPanel.isVisible()){
					vPanel.setVisible(true);
					iPanel.setVisible(false);
				}
			}
		});

		FlowPanel blankPanel = new FlowPanel();
		blankPanel.addStyleName("height40");
		FlowPanel bPanel = new FlowPanel();
		Button post = new Button("Post-It!");
		Button pin = new Button("Pin-It!");
		FlexTable fTable = new FlexTable();
		fTable.setWidget(0, 0, post);
		fTable.setWidget(0, 1, pin);
		bPanel.add(fTable);
		bPanel.addStyleName("floatRight");
		ClickHandler postHandler = new ClickHandler(){
			public void onClick(ClickEvent event) {
				boolean imageFormatCorrect = imageInputCorrect();
				boolean videoFormatCorrect = videoInputCorrect();
				boolean contentNull = isContentNull();

				if (!contentNull){
					if (!imageFormatCorrect){
						Window.alert("Image format incorrect! The system supports JPG, GIF, TIFF and PNG iamges.");
					}
					else if(!videoFormatCorrect){
						Window.alert("Only Youtube Videos are supported. Please paste the url of that video here.");
					}
					else{
						ClassCommonsMessage msg = getNewMessage(0);
						postMessage(msg, cid);
					}
				}

			}

		};
		ClickHandler pinHandler = new ClickHandler(){
			public void onClick(ClickEvent event) {
				boolean imageFormatCorrect = imageInputCorrect();
				boolean videoFormatCorrect = videoInputCorrect();
				boolean contentNull = isContentNull();

				if (!contentNull){
					if (!imageFormatCorrect){
						Window.alert("Image format incorrect! The system supports JPG, GIF, TIFF and PNG iamges.");
					}
					else if(!videoFormatCorrect){
						Window.alert("Only Youtube Videos are supported. Please paste the url of that video here.");
					}
					else{
						ClassCommonsMessage msg = getNewMessage(3);
						postMessage(msg, cid);
					}
				}

			}

		};
		post.addClickHandler(postHandler);
		pin.addClickHandler(pinHandler);

		fPanel.add(tip);
		fPanel.add(postArea);
		fPanel.add(postOptionsPanel);
		fPanel.add(iPanel);
		fPanel.add(vPanel);
		fPanel.add(blankPanel);
		fPanel.add(bPanel);


		return fPanel;
	}

	private void postMessage(final ClassCommonsMessage msg, final int cid) {
		// Initialize the service proxy.
		if (classCommonsServiceSvc == null) {
			classCommonsServiceSvc = GWT.create(ClassCommonsService.class);
		}
		// Set up the callback object.
		AsyncCallback<Boolean> callback = new AsyncCallback<Boolean>() {
			public void onFailure(Throwable caught) {
				caught.printStackTrace();
			}

			public void onSuccess(Boolean b) {
				if (!b){
					System.out.println("Error when posting this message!");
				}
				else{
					clearAllInputBoxes();
					/*
					cm_msgs.add(msg);
					if (msg.getType()==3){
						pin_msgs.add(msg);
					}
					else{
						stack_msgs.add(msg);
					}
					 */
					//refresheMessageList();
					loadCMMsgs(cid);
				}

			}
		};
		classCommonsServiceSvc.postMessage(msg, cid, callback);	
	}

	boolean isContentNull(){
		boolean contentNull = false;

		String content = postArea.getText();
		String videoURL = vBox.getText();
		String imageURL = iBox.getText();

		if (ClassConversationUtil.IsNullOrEmpty(content) && ClassConversationUtil.IsNullOrEmpty(videoURL) && ClassConversationUtil.IsNullOrEmpty(imageURL) ){
			contentNull = true;
		}

		return contentNull;
	}

	boolean imageInputCorrect(){
		boolean formatCorrect = false;
		String imageURL = iBox.getText();
		if (ClassConversationUtil.IsNullOrEmpty(imageURL)){
			return true;
		}
		else{
			String format = imageURL.trim().substring(imageURL.lastIndexOf(".")+1).toLowerCase();
			for (int i=0; i<imageFormats.length; i++){
				if (format.equals(imageFormats[i])){
					return true;
				}
			}
		}
		return formatCorrect;


	}

	boolean videoInputCorrect(){
		boolean videoCorrect = false;
		String videoURL = vBox.getText();
		if (ClassConversationUtil.IsNullOrEmpty(videoURL)){
			return true;
		}
		else{
			if (isYoutube(videoURL)){
				return true;
			}

		}
		return videoCorrect;
	}

	boolean isYoutube(String url){
		boolean isYoutube = false;
		if (url.contains("youtube.com") || url.contains("youtu.be")){
			isYoutube = true;
		}
		return isYoutube;	
	}

	public FlowPanel getVideoURLPanel(){
		FlowPanel fPanel = new FlowPanel();
		FlexTable fTable = new FlexTable();
		Label vLabel = new Label("URL of the video (Youtube only):");
		vBox= new TextBox();
		vBox.setWidth("400px");
		fTable.setWidget(0, 0, vLabel);
		fTable.setWidget(0, 1, vBox);
		fPanel.add(fTable);
		return fPanel;

	}

	public FlowPanel getImageURLPanel(){
		FlowPanel fPanel = new FlowPanel();
		FlexTable fTable = new FlexTable();
		Label iLabel = new Label("URL of the image:");
		iBox= new TextBox();
		iBox.setWidth("400px");
		fTable.setWidget(0, 0, iLabel);
		fTable.setWidget(0, 1, iBox);
		fPanel.add(fTable);
		return fPanel;

	}

	public FlowPanel getMessagePanel(){
		FlowPanel fPanel = new FlowPanel();
		FlowPanel headingPanel = new FlowPanel ();
		Label heading = new Label("Real Time Discussions");
		heading.addStyleDependentName("Heading");
		FlowPanel makeTopicPanel = new FlowPanel();


		final Anchor makeTopic = new Anchor("Make a Topic");
		final Anchor finish = new Anchor("Finish Selection");
		finish.setVisible(false);
		makeTopic.addClickHandler(new ClickHandler(){

			public void onClick(ClickEvent event) {
				showCheckBoxMessages();
				makeTopic.setVisible(false);
				finish.setVisible(true);
			}

		});
		finish.addClickHandler(new ClickHandler(){
			public void onClick(ClickEvent event) {

				ArrayList<ClassCommonsMessage> selected_msg = getSelectedMessages();
				if (selected_msg.size() <= 0) {
					Window.alert("no message is selected!");
				}
				else{
					String content = "";
					for (int i=0; i< selected_msg.size(); i++){
						ClassCommonsMessage m = selected_msg.get(i);
						content = content + "<br>" + m.getPoster().getFullName() + ": " +  m.getContent();
					}

					final GWTCPopupBox upload_box = new GWTCPopupBox(GWTCPopupBox.OPTION_ROUNDED_BLUE);
					ListBox forum_list = new ListBox(false);


					final FormPanel uploader_form_panel = new FormPanel();
					uploader_form_panel.setAction("http://cscl.ist.psu.edu:5678/classconversation/service/ForumService"); //need to change to the actual url that handles uploading
					uploader_form_panel.setEncoding(FormPanel.ENCODING_MULTIPART);
					uploader_form_panel.setMethod(FormPanel.METHOD_POST);

					CaptionPanel upload_caption_panel = new CaptionPanel("Make it a discussion topic in the class forum");

					final VerticalPanel upload_form_element_panel = new VerticalPanel();
					upload_caption_panel.add(upload_form_element_panel);
					uploader_form_panel.setWidget(upload_caption_panel);

					HorizontalPanel hpanel_0 = new HorizontalPanel();
					Label forum_list_label = new Label("Add it to: ");
					hpanel_0.add(forum_list_label);



					prepareDropdownList(Integer.toString(cid), forum_list);
					forum_list.addChangeHandler(new ChangeHandler() {
						public void onChange(ChangeEvent event) {
							ListBox list = (ListBox) event.getSource();
							Window.alert(list.getValue(list.getSelectedIndex()));
						}
					});
					forum_list.setName("parent_id");
					hpanel_0.add(forum_list);

					upload_form_element_panel.add(hpanel_0);


					HorizontalPanel hpanel_1 = new HorizontalPanel();
					Label title_label = new Label("Title: ");
					hpanel_1.add(title_label);
					TextBox title = new TextBox();
					title.setText("Untitled");
					title.setName("title");

					title.addFocusHandler(new FocusHandler() {
						public void onFocus(FocusEvent event) {
							TextBox box = (TextBox)event.getSource();
							String tmp_str = box.getText();
							if (tmp_str.equalsIgnoreCase("Untitled")) {
								box.setText("");
							}
							else {
								return;
							}
						}
					});

					title.addBlurHandler(new BlurHandler() {
						public void onBlur(BlurEvent event) {
							TextBox box = (TextBox)event.getSource();
							String tmp_str = box.getText();
							if (tmp_str.equalsIgnoreCase("Untitled") || tmp_str.trim().equalsIgnoreCase("")) {
								box.setText("Untitled");
							}
							else {
								return;
							}
						}
					});

					hpanel_1.add(title);
					upload_form_element_panel.add(hpanel_1);

					HorizontalPanel hpanel_2 = new HorizontalPanel();
					Label content_label = new Label("Content: ");
					hpanel_2.add(content_label);
					TextArea content_box = new TextArea();
					content_box.setSize("300px", "100px");
					content_box.setName("content");
					content_box.setText(content);
					hpanel_2.add(content_box);
					upload_form_element_panel.add(hpanel_2);

					content_box.addFocusHandler(new FocusHandler() {
						public void onFocus(FocusEvent event) {
							TextArea box = (TextArea)event.getSource();
							String tmp_str = box.getText();
							if (tmp_str.equalsIgnoreCase("Enter content here.")) {
								box.setText("");
							}
							else {
								return;
							}
						}
					});

					content_box.addBlurHandler(new BlurHandler() {
						public void onBlur(BlurEvent event) {
							TextArea box = (TextArea)event.getSource();
							String tmp_str = box.getText();
							if (tmp_str.equalsIgnoreCase("Enter content here.") || tmp_str.trim().equalsIgnoreCase("")) {
								box.setText("Enter content here.");
							}
							else {
								return;
							}
						}
					});


					Hidden operator = new Hidden();
					operator.setName("op");
					operator.setValue("addAttachment");
					upload_form_element_panel.add(operator);

					Hidden redirector = new Hidden();
					redirector.setName("redirect");
					redirector.setValue("null");
					upload_form_element_panel.add(redirector);

					Hidden hidden_itype_name = new Hidden();
					hidden_itype_name.setName("itype");
					hidden_itype_name.setValue("0");
					upload_form_element_panel.add(hidden_itype_name);

					Hidden hidden_user_name = new Hidden();
					hidden_user_name.setName("uid");
					hidden_user_name.setValue(user.getUid());
					//                hidden_itype_name.setValue(user.getUid());
					upload_form_element_panel.add(hidden_user_name);

					Hidden hidden_class_id = new Hidden();
					hidden_class_id.setName("cls");
					hidden_class_id.setValue(Integer.toString(cid));
					upload_form_element_panel.add(hidden_class_id);

					//              Hidden hidden_parent_id = new Hidden();
					//              hidden_parent_id.setName("parent_id");
					//              hidden_parent_id.setValue(forum_id);
					//              upload_form_element_panel.add(hidden_parent_id);

					Hidden hidden_object_type = new Hidden();
					hidden_object_type.setName("type");
					hidden_object_type.setValue("1");
					upload_form_element_panel.add(hidden_object_type);



					final FileUpload upload = new FileUpload() {
						{
							addDomHandler(new ChangeHandler() {


								public void onChange(
										ChangeEvent event) {
									FileUpload upload = (FileUpload)event.getSource();
									VerticalPanel upload_form_element_panel = (VerticalPanel) upload.getParent();
									int upload_idx = upload_form_element_panel.getWidgetIndex(upload);
									VerticalPanel file_list = (VerticalPanel) upload_form_element_panel.getWidget(upload_idx - 1);
									file_list.clear();
									String[] names = getFiles(((FileUpload)event.getSource()).getElement());
									for (int i = 0; i < names.length; i++) {
										file_list.add(new Label(names[i]));
									}
								}
							}, ChangeEvent.getType());
						}
					};
					upload.setName("fname");
					upload.getElement().setAttribute("multiple", "");
					upload_form_element_panel.add(new VerticalPanel());
					upload_form_element_panel.add(upload);


					// Add a 'submit' button.
					HTML submit_button = new HTML("<div>Submit<span/><div>");
					submit_button.setStyleName("round-button");
					submit_button.getElement().setId("round-button-g");
					submit_button.addClickHandler(new ClickHandler() {
						public void onClick(ClickEvent event) {
							String[] names = getFiles(upload.getElement());
							//                      if (names.length < 1) {
							//                          Window.alert("No file is selected!");
							//                          return;
							//                      }
							for (int i = 0; i < names.length; i++) {
								if (!names[i].substring(names[i].lastIndexOf('.') + 1).equalsIgnoreCase("pdf")) {
									//                            Window.alert("can't upload files not in pdf format");
									//                            return;
								}
							}
							uploader_form_panel.submit();
						}
					});

					HTML cancel_button = new HTML("<div>Cancel<span/><div>");
					cancel_button.setStyleName("round-button");
					cancel_button.getElement().setId("round-button-g");
					cancel_button.addClickHandler(new ClickHandler() {
						public void onClick(ClickEvent event) {
							upload_box.hide();
						}
					});

					HorizontalPanel submit_cancel_button_panel = new HorizontalPanel();
					submit_cancel_button_panel.add(submit_button);
					submit_cancel_button_panel.add(cancel_button);
					upload_form_element_panel.add(submit_cancel_button_panel);

					// Add an event handler to the form.
					uploader_form_panel.addSubmitHandler(new FormPanel.SubmitHandler() {
						public void onSubmit(SubmitEvent event) {
							String[] names = getFiles(upload.getElement());
							//                      if (names.length < 1) {
							//                          Window.alert("No file is selected!");
							//                      }
						}
					});
					uploader_form_panel.addSubmitCompleteHandler(new FormPanel.SubmitCompleteHandler() {
						public void onSubmitComplete(SubmitCompleteEvent event) {
							upload_box.hide();
						}
					});


					upload_box.add(uploader_form_panel);

					int X_ = calculateXposition(event.getNativeEvent().getClientX(), Window.getClientWidth(), 200);
					int Y_ = calculateYposition(event.getNativeEvent().getClientY(), Window.getClientHeight(), 100);
					if (event.getNativeEvent().getClientY() + 200 > Window.getClientHeight()) {
						upload_box.setPopupPosition(X_, Y_);
					}
					else {
						upload_box.setPopupPosition(X_, Y_);
					}
					upload_box.setZIndex(9999);
					upload_box.show();
				}

				refresheMessageList();
				setMesssagesUnchecked();
				finish.setVisible(false);
				makeTopic.setVisible(true);
			}

		});
		makeTopicPanel.add(makeTopic);
		makeTopicPanel.add(finish);


		headingPanel.add(heading);
		headingPanel.add(makeTopicPanel);
		fPanel.add(headingPanel);

		messageListPanel = new FlowPanel();
		fPanel.add(messageListPanel);
		return fPanel;
	}

	public void setMesssagesUnchecked(){
		for (int i=0; i< cm_msgs.size(); i++){
			cm_msgs.get(i).setChecked(false);
		}
	}

	public ArrayList<ClassCommonsMessage> getSelectedMessages(){
		ArrayList<ClassCommonsMessage> selected_msg = new ArrayList<ClassCommonsMessage>();
		for (int i=0; i< cm_msgs.size(); i++){
			ClassCommonsMessage msg = cm_msgs.get(i);
			boolean isSelected = msg.isChecked();
			if(isSelected){
				selected_msg.add(msg);
			}
		}
		return selected_msg;
	}

	private void loginFromSession(){
		// Initialize the service proxy.
		if (loginServiceSvc == null) {
			loginServiceSvc = GWT.create(LoginService.class);
		}
		// Set up the callback object.
		AsyncCallback<User> callback = new AsyncCallback<User>() {
			public void onFailure(Throwable caught) {
				caught.printStackTrace();
			}

			public void onSuccess(User u) {
				user = u;
				if (u == null){
					Window.Location.replace("http://cscllab.ist.psu.edu");
				}
				else{
					Log.debug(user.getFullName() +" comes in!");
					getCid(cname);
				}
			}
		};
		loginServiceSvc.loginFromSession(callback);
	}

	public ClassCommonsMessage getNewMessage(int type){
		User poster = this.user;
		String content = postArea.getText();
		String videoURL = vBox.getText();
		String imageURL = iBox.getText();
		Date postDate = new Date();
		boolean isTopic = false;
		int like = 0;
		ClassCommonsMessage msg = new ClassCommonsMessage(poster, cid, content, videoURL, imageURL, postDate,isTopic, like, type);
		return msg;
	}

	private void getCid(String course_name){
		// Initialize the service proxy.
		if (classCommonsServiceSvc == null) {
			classCommonsServiceSvc = GWT.create(ClassCommonsService.class);
		}
		// Set up the callback object.
		AsyncCallback<Integer> callback = new AsyncCallback<Integer>() {
			public void onFailure(Throwable caught) {
				caught.printStackTrace();
			}

			public void onSuccess(Integer course_id) {
				if (course_id == 0){
					Window.alert("No course find for this class name");
				}
				else{
					cid = course_id;
					setForumLink();
					loadCMMsgs(cid);
				}

			}
		};
		classCommonsServiceSvc.getCid(course_name, callback);	
	}

	public void setForumLink(){
		forumHeader.addClickHandler(new ClickHandler(){
			public void onClick(ClickEvent event) {
				Window.Location.replace("/classconversation/secured/CCForum.html?cls="+cid+"&cname="+cname);
			}

		});

	}

	private void clearAllInputBoxes(){
		postArea.setText("");
		vBox.setText("");
		iBox.setText("");
	}

	private void loadCMMsgs(int course_id){
		// Initialize the service proxy.
		if (classCommonsServiceSvc == null) {
			classCommonsServiceSvc = GWT.create(ClassCommonsService.class);
		}
		// Set up the callback object.
		AsyncCallback<ArrayList<ClassCommonsMessage>> callback = new AsyncCallback<ArrayList<ClassCommonsMessage>>() {
			public void onFailure(Throwable caught) {
				caught.printStackTrace();
			}

			public void onSuccess(ArrayList<ClassCommonsMessage> msgs) {
				cm_msgs = msgs;
				//distinguishMessages();
				refresheMessageList();
			}
		};
		classCommonsServiceSvc.loadClassCommonsMsgs(course_id, callback);	

	}

	public void distinguishMessages(){
		pin_msgs = new ArrayList<ClassCommonsMessage>();
		stack_msgs = new ArrayList<ClassCommonsMessage>();
		for (int i=0; i<cm_msgs.size(); i++){
			ClassCommonsMessage msg = cm_msgs.get(i);
			int type = msg.getType();
			if (type == 3){
				pin_msgs.add(msg);
			}
			else{
				stack_msgs.add(msg);
			}
		}
	}

	public void refresheMessageList(){
		messageListPanel.clear();
		addMessages();
		//addPinPanel();
		//addMessageStackPanel();
	}

	public void addMessages(){
		int length = cm_msgs.size();
		int width = (int) (0.6*Window.getClientWidth());
		if (length > 0){
			for (int i=0; i<length; i++){
				ClassCommonsMessage cms = cm_msgs.get(i);
				FlowPanel temp;
				if (cms.getType()== 3){
					temp = cm_msgs.get(i).getPinBox(width);

				}
				else{
					temp = cm_msgs.get(i).getMessageBox(width);

				}

				messageListPanel.add(temp);
			}
		}

	}


	// construct the panel that lists the pins
	public void addPinPanel(){
		int length = pin_msgs.size();
		int width = (int) (0.6*Window.getClientWidth());
		if (length > 0){
			for (int i=0; i<length; i++){

				FlowPanel temp = pin_msgs.get(i).getPinBox(width);
				if (i%2 == 1){
					//temp.addStyleName("gray-backgroundcolor");
				}
				messageListPanel.add(temp);
			}
		}


	}

	// construct the message stack panel
	public void addMessageStackPanel(){
		int length = stack_msgs.size();
		int width = (int) (0.6*Window.getClientWidth());
		if (length > 0){
			for (int i=0; i<length; i++){
				FlowPanel temp = stack_msgs.get(i).getMessageBox(width);
				if (i%2 == 1){
					//temp.addStyleName("gray-backgroundcolor");
				}
				messageListPanel.add(temp);
			}
		}

	}
	public void showCheckBoxMessages(){
		messageListPanel.clear();
		addCheckBoxMessages();
		//addPinCheckBoxMessages();
		//addPostCheckboxMessages();

	}

	public void addCheckBoxMessages(){
		int length = this.cm_msgs.size();
		int width = (int) (0.6*Window.getClientWidth()+10);
		if (length > 0){
			for (int i=0; i< length; i++){

				FlowPanel temp = cm_msgs.get(i).getMessageBoxCheckable(width);
				messageListPanel.add(temp);
			}
		}


	}

	public void addPinCheckBoxMessages(){
		int length = this.pin_msgs.size();
		int width = (int) (0.6*Window.getClientWidth()+10);
		if (length > 0){
			for (int i=0; i< length; i++){

				FlowPanel temp = pin_msgs.get(i).getMessageBoxCheckable(width);
				messageListPanel.add(temp);
			}
		}

	}

	public void addPostCheckboxMessages(){
		int length = this.stack_msgs.size();
		int width = (int) (0.6*Window.getClientWidth()+10);
		if (length > 0){
			for (int i=0; i< length; i++){
				FlowPanel temp = stack_msgs.get(i).getMessageBoxCheckable(width);
				messageListPanel.add(temp);
			}
		}

	}

	protected void prepareDropdownList(String cls_id, ListBox list) {
		final ListBox forum_list = list;
		String url = "http://cscl.ist.psu.edu:5678/classconversation/service/ForumService";
		String postData = "op=gforums&t=0&o=time asc&cls=" + cls_id;
		RequestBuilder builder = new RequestBuilder(RequestBuilder.POST, url);
		builder.setHeader("Content-type", "application/x-www-form-urlencoded");
		try {
			Request request = builder.sendRequest(postData, new RequestCallback() {
				public void onError(Request request, Throwable exception) {
				}

				public void onResponseReceived(Request request, Response response) {
					if (200 == response.getStatusCode()) {
						forum_list.clear();
						forum_list.addItem("Select...", "unselected");
						JsArray<CommonObject> forums = asArrayOfCommonObject(response.getText());
						CommonObject forum;
						for (int i = 0; i < forums.length(); i++) { 
							forum = forums.get(i);
							forum_list.addItem(forum.getContent(), forum.getId());
						}
					} else {
					}                
				}
			});
		} catch (RequestException e) {
		}
	}

	public native String[] getFiles(Element upload) /*-{
        var input = upload;
        var names = new Array();       
               for (var i = 0; i < input.files.length; i++) {
               names[i] = input.files[i].name;
    //            $wnd.alert(input.files[i].name);
               }
        return names;
    }-*/;

	private final native JsArray<CommonObject> asArrayOfCommonObject(String json) /*-{
        return eval(json);
    }-*/;

	public int calculateXposition(int mouse_x, int window_width, int object_width){
		if (mouse_x + object_width > window_width) {
			return mouse_x - object_width;
		}
		else {
			return mouse_x;
		}
	}

	public int calculateYposition(int mouse_y, int window_heigth, int object_heigth){
		if (mouse_y + object_heigth > window_heigth) {
			return mouse_y - object_heigth;
		}
		else {
			return mouse_y;
		}
	}

}
